﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Threading.Tasks;
using System.Text;
using System.Threading;
using Microsoft.AspNet.SignalR.Client;
using MudClassSkeleton;

namespace WcfBusinessLogic
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
    // NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging.
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class Service1 : IBusinessLogic
    {
        static Model.WorldContainer OurWorld = new Model.WorldContainer();
        RecordManager RM = new RecordManager();

        public void SendCommand(string ID, string message)
            //passes commands from users to game worlds command parser
        {
            //Model.HubCommunication.broadcast("System", message, "main");
            //Model.HubCommunication.broadcast("System", message.Length.ToString(), "main");
            try
            {
                // Get player object from game state in GM
                PlayerCharacter pc = OurWorld.GM.GetCharacter(ID);
                //Model.HubCommunication.broadcast("System", pc.ID.ToString(), "main");
                // Send command to player for pressessing and return a response object
                Response r =  pc.ProcessCommandString(message).Result;
                //Model.HubCommunication.broadcast("System", r.Messages.Count.ToString(), "main");
                // cycle through messages in the response object and send them out to each user.
                foreach(Response.Message m in r.Messages)
                {
                    //Model.HubCommunication.broadcast(m.CharacterID, m.Text, m.Type);
                    Model.HubCommunication.sendTo(m.CharacterID, m.Text, m.Type);
                }
                //Model.HubCommunication.broadcast("Server", r.Messages[0].CharacterID.ToString() + r.Messages[0].Text.ToString() + r.Messages[0].Type.ToString(), "main");
            }
            catch (Exception EE)
            {
                Console.WriteLine(EE.StackTrace);
                //Model.HubCommunication.broadcast("Server", EE.StackTrace.ToString(), "main");
                return;
            }
             
            
           // Model.HubCommunication.sendTo(ID, message, "main");
            
        }

        public UserDetails LogIn(UserDetails aUser)
            //Validates a user login and returns their id
            //if user info is invalid it returns an id of 0
        {

            UserDetails user = new UserDetails();
            List<SqlParameter> userParams = new List<SqlParameter>();
            userParams.Add(new SqlParameter("@Name", aUser.UserName.ToString()));
            userParams.Add(new SqlParameter("@Pass", aUser.UserKey.ToString()));
            try
            {
                DataTable DT = RM.SendReadRequest("mspValidateUser", userParams);
                DataRow DR = DT.Rows[0];
                user.UserID = Convert.ToInt32(DR["ID"].ToString());
                user.UserName = DR["UserName"].ToString();
                user.Email = DR["Email"].ToString();
                user.UserKey = "";
            }
            catch(Exception EE)
            {
                user.UserID = 0;
                user.UserName = "";
                user.Email = "";
                user.UserKey = "";
            }
            return user;
        }

        public void LogOut(UserDetails aUser)
            //Logs a user out of the system
            //disposing of any variables they have and 
            //removes their characters from any game they are in
        {
            
        }

        //register new user and return an int error code 0 being successful
        public string Register(UserDetails aUser)
            //Registers a new user and returns a message detailing success or failure
        {
            int id= 0;
            List<SqlParameter> userParams = new List<SqlParameter>();
            userParams.Add(new SqlParameter("@UserName", aUser.UserName.ToString()));
            userParams.Add(new SqlParameter("@Email", aUser.Email.ToString()));
            userParams.Add(new SqlParameter("@Password", aUser.UserKey.ToString()));
            id = RM.SendWriteRequest("mspRegister", userParams);
            string RegisterMessage = null;// = "Not Implemented Yet";
            if(id == 0)
            {
                RegisterMessage = "Unable to Create User, User Name Taken " + id;
            }
            else
            {
                RegisterMessage = "Successfully Registered! " + id;
            }
            //string RegisterMessage = "Not Implemented Yet";
            return RegisterMessage;
        }

        public void ConnectCharacter(string characterID)
            //tells a game to load a character and who to send its messages to
        {
            //PlayerCharacter pc = OurWorld.GM.AddCharacter(characterID);
            PlayerCharacter pc = OurWorld.GM.AddCharacter(characterID);
        }

        public CharacterInFo[] GetCharacters(string userID)
            //Get a list of the players characters for them to view
        {
            List<CharacterInFo> myCharacters = new List<CharacterInFo>();
            List<SqlParameter> userParams = new List<SqlParameter>();
            userParams.Add(new SqlParameter("@userID", Convert.ToInt32(userID) ) );
            DataTable dt = RM.SendReadRequest("mspGetCharacterlist", userParams);
            foreach (DataRow aRow in dt.Rows)
            {
                CharacterInFo myCharacter = new CharacterInFo();
                    myCharacter.CharName = aRow["Name"].ToString();
                    myCharacter.CharID = Convert.ToInt32(aRow["ID"]);
                    myCharacter.CharDescription = aRow["Description"].ToString();
                    myCharacter.CharHP = Convert.ToInt32(aRow["maxHP"]);
                    myCharacter.CharMP = Convert.ToInt32(aRow["maxMP"]);
                    myCharacter.CharStr = Convert.ToInt32(aRow["Str"]);
                    myCharacter.CharDex = Convert.ToInt32(aRow["Dex"]);
                    myCharacter.CharInt = Convert.ToInt32(aRow["Int"]);
                    myCharacters.Add(myCharacter);
            }
            return myCharacters.ToArray();
        }

        public string SaveCharacter(CharacterInFo character)
            //check and creat a character for the game and return a message detailing success or failure
        {
            string createMessage = "";
            PlayerCharacter saveChar = null;
            if(character.CharID == 0)
            {
                saveChar = new PlayerCharacter();
                saveChar.CurrentHP = character.CharHP;
                saveChar.CurrentMP = character.CharMP;
                saveChar.setUserID(character.UserID);
            }
            else
            {
                saveChar = new PlayerCharacter(character.CharID);

            }

            saveChar.Name = character.CharName;
            saveChar.Description = character.CharDescription;
            saveChar.MaximumHP = character.CharHP;
            saveChar.MaximumMP = character.CharMP;
            saveChar.Strength = character.CharStr;
            saveChar.Dexterity = character.CharDex;
            saveChar.Intelligence = character.CharInt;
            //saveChar.ID = Convert.ToInt32(character.CharID);
            //createMessage = "not implemented yet";
            bool success = saveChar.Save();
            if(success)
            {
                createMessage = "Successfully Saved your character!";
            }
            return createMessage;
            
        }

        public GameNews[] GetNews()
            //get the news feed for a user who has just logged in
        {
            // return test data for news

              List<GameNews> theNews = new List<GameNews>();
              List<SqlParameter> userParams = new List<SqlParameter>();
              DataTable dt = RM.SendReadRequest("mspGetNews", userParams);
              foreach (DataRow aRow in dt.Rows)
              {
                  GameNews newsItem = new GameNews();
                  CharacterInFo myCharacter = new CharacterInFo();
                  newsItem.Headline = aRow["Headline"].ToString();
                  newsItem.Date = aRow["nDate"].ToString();
                  newsItem.Details = aRow["Details"].ToString();
                  theNews.Add(newsItem);
              }
            return theNews.ToArray();
        }

        public void NewNews(GameNews someNews)
            //adds a new artical to the news feed
        {
            
        }

        public void DeleteNews(GameNews someNews)
            //deletes an artical from the news feed
        {
            
        }
        /*
        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }
         */
    }
}
